
#include <array>
#include <cassert>
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;
template <typename T, int dimension> class var {
public:
  var() = default;
  var(int dim1) : sz{1} { wiget(0, dim1); }
  var(int dim1, int dim2) : sz{1} {
    wiget(0, dim1, dim2);
    elem = new T[sz];
  }
  // var()

private:
  array<int, dimension> dim;
  T *elem;
  int sz;

  void wiget(int tmp){};
  template <typename C, typename... types>
  void wiget(int index, C a, types... args) {
    dim[index] = a;
    sz *= a;
    ++index;
    wiget(index, args...);
  }
};

template <typename T, int dimension> struct test {
public:
  test() = default;
  template <typename... Dims> test(Dims... dims) {
    static_assert(dimension == sizeof...(Dims), "not match\n");
    // 这能运行
    // auto tmp{(... * dims)};
    // cout << typeid(dims...).name() << endl;
    dim_ = {dims...};
    size_ = CalcSize();
    elem_ = new T[size_];
  }

  void print() {
    for (size_t i = 0; i < dimension; ++i) {
      cout << dim_[i] << endl;
    }
    cout << size_ << endl;
  }

  // 不能用此来对函数 进行取舍
  // if constexpr (dimension == 2) {
  //   void pnt() { cout << "hello\n"; }
  // } else {
  //   void app() { cout << "not good\n"; }
  // }

private:
  array<int, dimension> dim_;
  T *elem_;
  int size_;

  int CalcSize() {
    int tmp{1};
    for (int i = 0; i < dimension; ++i)
      tmp *= dim_[i];
    return tmp;
  }
};

int main() {
  test<double, 3> obj1(1, 2, 3), obj2(4, 5, 6);
  obj1.print();
  obj2.print();
  return 0;
}